#include "preHeader.h"
#include "GameConfig.h"

ShellOfGameConfig::ShellOfGameConfig()
: m_cfgInst(NULL)
{
}

ShellOfGameConfig::~ShellOfGameConfig()
{
	delete m_cfgInst;
	for (auto cfgInst : m_obsoleteInsts) {
		delete cfgInst;
	}
}

bool ShellOfGameConfig::LoadNewCfgInst()
{
	auto cfgInst = new GameConfigInstance;
	cfgInst->InitData();
	SaveCfgInst(cfgInst);
	return true;
}

void ShellOfGameConfig::SaveCfgInst(GameConfigInstance* cfgInst)
{
	if (m_cfgInst != NULL) {
		m_obsoleteInsts.push_back(m_cfgInst);
	}
	m_cfgInst = cfgInst;
}

void GameConfigInstance::InitData()
{
	auto pCfgTbl = sDBMgr.GetTable<Configure>();
	std::unordered_map<std::string_view, const Configure*> cfgMaps;
	cfgMaps.reserve(pCfgTbl->GetNumRows());
	for (auto itr = pCfgTbl->VBegin(); itr != pCfgTbl->VEnd(); ++itr) {
		cfgMaps.emplace(std::string_view(itr->cfgName), &*itr);
	}

	#define GetConfigValue(Name) \
		funcGetConfigValue(std::string_view(Name, sizeof(Name)-1))
	auto funcGetConfigValue = [&](const std::string_view& cfgName) {
		auto itr = cfgMaps.find(cfgName);
		return itr != cfgMaps.end() ? itr->second->cfgVal.c_str() : "";
	};

	const char* cfgVal = GetConfigValue("MaxPlayerLevel");
	MaxPlayerLevel = atoi(cfgVal);

	cfgVal = GetConfigValue("BornPosition");
	TextUnpacker unpacker(cfgVal);
	unpacker >> BornMapType >> BornMapID
		>> BornPos.x >> BornPos.y >> BornPos.z >> BornPos.o;

	cfgVal = GetConfigValue("MapTypeViewingDistances");
	unpacker.SetIterator(cfgVal);
	while (!unpacker.IsEmpty()) {
		uint32 mapType;
		float viewingDistance;
		unpacker >> mapType >> viewingDistance;
		MapTypeViewingDistances.emplace(mapType, viewingDistance);
	}

	cfgVal = GetConfigValue("PlayBoss");
	unpacker.SetIterator(cfgVal);
	unpacker >> PlayBossMapId >> PlayBossMemberMax;
	while (!unpacker.IsEmpty()) {
		PlayBossSpawns.push_back(unpacker.Unpack<uint32>());
	}

	cfgVal = GetConfigValue("GuildLeague");
	GuildLeagueMapId = atoi(cfgVal);
}
